package com.innovation.ic.im.end.web.endpoint;

import com.innovation.ic.b1b.framework.manager.RedisManager;
import com.innovation.ic.b1b.framework.manager.SftpChannelManager;
import com.innovation.ic.b1b.framework.manager.ThreadPoolManager;
import com.innovation.ic.im.end.base.handler.im_erp9.ModelHandler;
import com.innovation.ic.im.end.base.handler.im_erp9.RabbitMqHandler;
import com.innovation.ic.im.end.base.model.im_erp9.Account;
import com.innovation.ic.im.end.base.model.im_erp9.GroupMessage;
import com.innovation.ic.im.end.base.model.im_erp9.Message;
import com.innovation.ic.im.end.base.model.im_erp9.UserGroupMessage;
import com.innovation.ic.im.end.base.pojo.ServiceResult;
import com.innovation.ic.im.end.base.pojo.constant.Constants;
import com.innovation.ic.im.end.base.pojo.enums.AccountIntegrationEnum;
import com.innovation.ic.im.end.base.service.im_erp9.*;
import com.innovation.ic.b1b.framework.util.YamlUtil;
import com.innovation.ic.im.end.base.thread.web.UpdateUserGroupMessageThread;
import com.innovation.ic.im.end.base.value.config.*;
import com.innovation.ic.im.end.base.vo.im_erp9.GroupMessageVo;
import com.innovation.ic.im.end.base.vo.im_erp9.MessageVo;
import com.innovation.ic.im.end.base.vo.im_erp9.UserGroupMessageVo;
import com.innovation.ic.im.end.base.thread.web.UpdateLastContactTimeInChatPairThread;
import org.apache.curator.framework.CuratorFramework;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 抽象的websocket类
 */
public abstract class AbstractEndpoint {
    protected static UserGroupService userGroupService;

    protected static AccountService accountService;

    protected static GroupService groupService;

    protected static ChatPairService chatPairService;

    protected static RefGroupAccountService refGroupAccountService;

    protected static RefUserGroupAccountService refUserGroupAccountService;

    protected static ClientService clientService;

    public static CuratorFramework curatorFramework;

    protected static RabbitMqHandler rabbitMqHandler;

    protected static ModelHandler modelHandler;

    protected static ZookeeperParamConfig zookeeperParamConfig;

    protected static PictureParamConfig pictureParamConfig;

    protected static SftpParamConfig sftpParamConfig;

    protected static FileParamConfig fileParamConfig;

    protected static RabbitMqParamConfig rabbitMqParamConfig;

    protected static MinioConfig minioConfig;

    protected static ZookeeperPathWebParamConfig zookeeperPathWebParamConfig;

    protected static RedisManager redisManager;

    protected static ThreadPoolManager threadPoolManager;

    protected static SftpChannelManager sftpChannelManager;

    /**
     * 在线用户名单
     */
    public static Map<String, Endpoint> onlineMap = new ConcurrentHashMap<String, Endpoint>();

    /**
     * 在线默认群组名单
     */
    public static Map<String, Set<GroupEndpoint>> onlineGroupMap = new ConcurrentHashMap<String, Set<GroupEndpoint>>();

    /**
     * 在线用户自定义群组名单
     */
    public static Map<String, Set<UserGroupEndpoint>> onlineUserGroupMap = new ConcurrentHashMap<String, Set<UserGroupEndpoint>>();

    /**
     * 在线用户上传文件
     */
    protected static Map<String, MessageVo> onlineUploadMap = new ConcurrentHashMap<String, MessageVo>();

    /**
     * 在线默认群组用户上传文件
     */
    protected static Map<String, GroupMessageVo> onlineGroupUploadMap = new ConcurrentHashMap<String, GroupMessageVo>();

    /**
     * 在线用户自定义群组用户上传文件
     */
    protected static Map<String, UserGroupMessageVo> onlineUserGroupUploadMap = new ConcurrentHashMap<String, UserGroupMessageVo>();

    /**
     * 上传文件的存储路径
     */
    protected static String bucketName = null;

//    @Autowired
//    public void setMinioManager(MinioManager minioManager) {
//        AbstractEndpoint.minioManager = minioManager;
//    }

//    @Autowired
//    public void setRefGroupAccountOperationService(RefGroupAccountOperationService refGroupAccountOperationService) {
//        AbstractEndpoint.refGroupAccountOperationService = refGroupAccountOperationService;
//    }

    @Autowired
    public void setBucketName(RunEnvConfig runEnvConfig) {
        if(bucketName == null){
            bucketName = YamlUtil.getPropertyValue(runEnvConfig.getEnv(), "minio", "bucketName");
        }
    }

    @Autowired
    public void setAccountService(AccountService accountService) {
        AbstractEndpoint.accountService = accountService;
    }

    @Autowired
    public void setModelHandler(ModelHandler modelHandler) {
        AbstractEndpoint.modelHandler = modelHandler;
    }

    @Autowired
    public void setUserGroupService(UserGroupService userGroupService) {
        AbstractEndpoint.userGroupService = userGroupService;
    }

    @Autowired
    public void setGroupService(GroupService groupService) {
        AbstractEndpoint.groupService = groupService;
    }

    @Autowired
    public void setCuratorFramework(CuratorFramework curatorFramework) {
        AbstractEndpoint.curatorFramework = curatorFramework;
    }

    @Autowired
    public void setZookeeperParamConfig(ZookeeperParamConfig zookeeperParamConfig) {
        AbstractEndpoint.zookeeperParamConfig = zookeeperParamConfig;
    }

    @Autowired
    public void setPictureParamConfig(PictureParamConfig pictureParamConfig) {
        AbstractEndpoint.pictureParamConfig = pictureParamConfig;
    }

    @Autowired
    public void setSftpParamConfig(SftpParamConfig sftpParamConfig) {
        AbstractEndpoint.sftpParamConfig = sftpParamConfig;
    }

    @Autowired
    public void setFileParamConfig(FileParamConfig fileParamConfig) {
        AbstractEndpoint.fileParamConfig = fileParamConfig;
    }

    @Autowired
    public void setRabbitMqExchangeConfig(RabbitMqParamConfig rabbitMqParamConfig) {
        AbstractEndpoint.rabbitMqParamConfig = rabbitMqParamConfig;
    }

    @Autowired
    public void setRedisManager(RedisManager redisManager) {
        AbstractEndpoint.redisManager = redisManager;
    }

    @Autowired
    public void setThreadPoolManager(ThreadPoolManager threadPoolManager) {
        AbstractEndpoint.threadPoolManager = threadPoolManager;
    }

    @Autowired
    public void setSftpChannelManager(SftpChannelManager sftpChannelManager) {
        AbstractEndpoint.sftpChannelManager = sftpChannelManager;
    }

    @Autowired
    public void setZookeeperPathWebParamConfig(ZookeeperPathWebParamConfig zookeeperPathWebParamConfig) {
        AbstractEndpoint.zookeeperPathWebParamConfig = zookeeperPathWebParamConfig;
    }

    @Autowired
    public void setRefGroupAccountService(RefGroupAccountService refGroupAccountService) {
        AbstractEndpoint.refGroupAccountService = refGroupAccountService;
    }

    @Autowired
    public void setChatPairService(ChatPairService chatPairService) {
        AbstractEndpoint.chatPairService = chatPairService;
    }

    @Autowired
    public void setRefUserGroupAccountService(RefUserGroupAccountService refUserGroupAccountService) {
        AbstractEndpoint.refUserGroupAccountService = refUserGroupAccountService;
    }

    @Autowired
    public void setClientService(ClientService clientService) {
        AbstractEndpoint.clientService = clientService;
    }

    @Autowired
    public void setRabbitMqHandler(RabbitMqHandler rabbitMqHandler) {
        AbstractEndpoint.rabbitMqHandler = rabbitMqHandler;
    }

    /**
     * 更新chat_pair表的last_contact_time字段，两条记录都要更新
     * @param message
     */
    protected void updateLastContactTimeInChatPair(Message message){
        UpdateLastContactTimeInChatPairThread updateLastContactTimeInChatPairThread = new UpdateLastContactTimeInChatPairThread(message);
        threadPoolManager.execute(updateLastContactTimeInChatPairThread);
    }

    /**
     * 根据groupId，修改对应记录的last_contact_time字段
     * @param groupMessage
     */
    protected void updateLastContactTimeInRefGroupAccountThread(GroupMessage groupMessage){
        UpdateUserGroupMessageThread.UpdateLastContactTimeInRefGroupAccountThread updateLastContactTimeInRefGroupAccountThread = new UpdateUserGroupMessageThread.UpdateLastContactTimeInRefGroupAccountThread(groupMessage);
        threadPoolManager.execute(updateLastContactTimeInRefGroupAccountThread);
    }

    /**
     * 根据userGroupId，修改对应记录的last_contact_time字段
     * @param userGroupMessage
     */
    protected void updateLastContactTimeInRefUserGroupAccountThread(UserGroupMessage userGroupMessage){
        UpdateUserGroupMessageThread.UpdateLastContactTimeInRefUserGroupAccountThread updateLastContactTimeInRefUserGroupAccountThread = new UpdateUserGroupMessageThread.UpdateLastContactTimeInRefUserGroupAccountThread(userGroupMessage);
        threadPoolManager.execute(updateLastContactTimeInRefUserGroupAccountThread);
    }

    /**
     * 获取登录类型
     * @return 返回登录类型
     */
    protected List<Integer> getLoginTypeList(){
        ServiceResult<List<Integer>> result = clientService.getLoginTypeList();
        return result.getResult();
    }

    /**
     * 根据session参数获取登录类型
     * @param userProperties 用户参数
     * @return 返回登录类型
     */
    protected Integer getLoginType(Map<String, Object> userProperties){
        String clientId = (String) userProperties.get(Constants.CLIENT_ID);
        ServiceResult<Integer> clientResult = clientService.getTypeById(clientId);
        return clientResult.getResult();
    }

    /**
     * 获取账号类别
     * @param toUserAccount 接收消息的用户账号
     * @return 返回结果
     */
    protected Integer getIntegration(String toUserAccount){
        Integer integration = AccountIntegrationEnum.ERP_CORRELATION.getCode();
        ServiceResult<Account> serviceResult = accountService.findByAccount(toUserAccount);
        Account account = serviceResult.getResult();
        if(account != null && account.getIntegration() != null){
            integration = account.getIntegration();
        }
        return integration;
    }
}